/*
 * Copyright (c) 2008-2018, RF-Embedded GmbH
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 *  1. Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice, 
 *     this list of conditions and the following disclaimer in the 
 *     documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
 * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.Linq;
using System.Net;

using CSrfeReaderInterface.device;
using CSrfeReaderInterface.impl.device;
using CSrfeReaderInterface;

namespace CSrfeTest_ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("");
            Console.WriteLine("=============================================================");
            Console.WriteLine("|| Welcome to the RF-Embedded Open Source Protocol-Handler ||");
            Console.WriteLine("=============================================================");

            // Create instance of test program
            TestProgram t = new TestProgramExtended();

            IProtocolDeviceInterface dev = null;
            TestProgram.ReaderType type = TestProgram.ReaderType.STANDARD;

            if (!t.getTestConnection(out dev, out type))
            {
                if (!getProtocolDevice(out dev))
                    return;
            }

            // Initialize test program
            if (!t.init(dev, type))
            {
                return;
            }

            // Execute the tests
            while (true)
            {
                if (t.exec() == false)
                    break;
            }

            dev.Close();
        }

        static bool getProtocolDevice(out IProtocolDeviceInterface dev)
        {
            dev = null;

            // Get the serial device where the reader is connected to
            while (true)
            {

                Console.WriteLine("\n\n");
                Console.Write("Select connection type: 's' for serial, 't' for tcp and 'q' for quit (s)> ");

                string connectionType = Console.ReadLine();

                if (connectionType == "s" || connectionType == "")
                {
                    Console.WriteLine("Available COM Ports: ");
                    // get all available port names
                    string[] theSerialPortNames = System.IO.Ports.SerialPort.GetPortNames();

                    // print them out with index to select
                    for (int i = 0; i < theSerialPortNames.Length; i++)
                    {
                        Console.WriteLine("\t [ {0:d} ]: {1}", i, theSerialPortNames[i]);
                    }
                    Console.Write("Please select the index of the COM Port of the reader (Enter 'q' to Quit): [0]> ");
                    string port = Console.ReadLine();

                    if (port == "q")
                        return false;

                    try
                    {
                        int index = 0;
                        if (port.Length != 0)
                            index = Convert.ToInt32(port);

                        if (index < theSerialPortNames.Count())
                        {
                            // try to open the serial port
                            dev = new SerialDevice(theSerialPortNames[index]);
                            if (dev.Open())
                            {
                                Console.WriteLine("The COM-Port was open successfully");
                                return true;
                            }
                            else
                            {
                                Console.WriteLine("Could not open the COM-Port.");
                            }
                        }
                        else
                        {
                            Console.WriteLine("Index not in range.");
                        }
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("Could not convert input.");
                    }
                }
                //in case of tcp:
                else if (connectionType == "t")
                {
                    Console.Write("Please type ip address (127.0.0.1)> ");
                    string ipAddressString = Console.ReadLine();

                    Console.Write("Please type port (52475)> ");
                    string portString = Console.ReadLine();

                    try
                    {
                        int port = 52475;
                        if (portString != "")
                            port = int.Parse(portString);

                        IPAddress ip = IPAddress.Parse("127.0.0.1");
                        if (ipAddressString != "")
                            IPAddress.Parse(ipAddressString);

                        dev = new TCPDevice(ip, port);
                        //try to connect over tcp
                        if (dev.Open())
                        {
                            Console.WriteLine("The TCP-Socket was open successfully");
                            return true;
                        }
                        else
                        {
                            Console.WriteLine("Could not open the TCP-Socket.");
                        }
                    }
                    catch (FormatException /*formatException*/)
                    {
                        Console.WriteLine("Invalid address or port input");
                    }

                }
                else if (connectionType == "q")
                    return false;
                else
                {
                    Console.WriteLine("Unknown connection type >>" + connectionType + "<< entered.");
                }
            }
        }

    }
}
